using Godot;
using System;
using System.Collections.Generic;

namespace DRE.TextWriter {
	public static class Settings {
		// Template structures
		public struct ColorGradient {
			public ColorGradient(Color color) {
				Up = color;
				Down = color;
			}
			public ColorGradient(Color up, Color down) {
				Up = up;
				Down = down;
			}
			public Color Up { get; set; }
			public Color Down { get; set; }
		}
		public struct ColorSet {
			public ColorSet(ColorGradient text, ColorGradient shadow) {
				Text = text;
				Shadow = shadow;
			}
			public ColorGradient Text { get; set; }
			public ColorGradient Shadow { get; set; }
		}
		public struct FontResource {
			public FontResource(string path, Vector2? scale, Vector2? spacing) {
				Path = path;
				Scale = scale.HasValue ? scale.Value : new Vector2(2, 2);
				Spacing = spacing.HasValue ? spacing.Value : new Vector2(0, 0);
			}
			public string Path { get; set; }
			public Vector2 Scale { get; set; }
			public Vector2 Spacing { get; set; }
		}
		public struct FontSet {
			public FontSet(FontResource ascii, FontResource unicode) {
				ASCII = ascii;
				Unicode = unicode;
			}
			public FontResource ASCII { get; set; }
			public FontResource Unicode { get; set; }
			public FontResource GetFontResource(char character) => character < byte.MaxValue ? ASCII : Unicode;
		}
		public class VoiceProcessor {
			public virtual void OnWrite(TextWriter sender, string[] param, AudioStreamPlayer audio) {

			}
			public virtual void OnStartWriting(TextWriter sender, string[] param, AudioStreamPlayer audio) {

			}
			public virtual void OnStopWriting(TextWriter sender, string[] param, AudioStreamPlayer audio) {

			}
			public static class Defination {
				public class Generic : VoiceProcessor {

				}
			}
		}
		public struct SpecialChar {
			public SpecialChar(bool time, bool voice, bool visible) {
				Time = time;
				Voice = voice;
				Visible = visible;
			}
			public bool Time { get; set; }
			public bool Voice { get; set; }
			public bool Visible { get; set; }
		}

		// Template data
		public static Dictionary<string, ColorSet> ColorSets { get; } = new Dictionary<string, ColorSet>(){
			{
				"White",new ColorSet(
					new ColorGradient(Colors.White),
					new ColorGradient(
						new Godot.Color(0.19215687f, 0.19215687f, 0.30980393f),
						new Godot.Color(0.05882353f, 0.05882353f, 0.4509804f)
					)
				)
			},
			{
				"Gray",new ColorSet(
					new ColorGradient(new Godot.Color(64/255f, 64/255f, 64/255f)),
					new ColorGradient(new Godot.Color(20/255f, 20/255f, 20/255f))
				)
			},
			{
				"Red",new ColorSet(
					new ColorGradient(
						new Godot.Color(1, 0.7647059f, 0.7647059f),
						new Godot.Color(1, 0.23529412f, 0.23529412f)
					),
					new ColorGradient(new Godot.Color(0.29803923f, 0, 0))
				)
			},
			{
				"PureRed",new ColorSet(
					new ColorGradient(new Godot.Color(1, 0, 0)),
					new ColorGradient(new Godot.Color(0.29803923f, 0, 0))
				)
			},
			{
				"Yellow",new ColorSet(
					new ColorGradient(
						new Godot.Color(1, 1, 0.7647059f),
						new Godot.Color(1, 1, 0.23529412f)
					),
					new ColorGradient(new Godot.Color(0.29803923f, 0.29803923f, 0))
				)
			},
			{
				"PureYellow",new ColorSet(
					new ColorGradient(new Godot.Color(1, 1, 0)),
					new ColorGradient(new Godot.Color(0.29803923f, 0.29803923f, 0))
				)
			},
		};
		public static Dictionary<string, FontSet> FontSets { get; } = new Dictionary<string, FontSet>(){
			{"Default",new FontSet(
				new FontResource("res://Fonts/DeterminationMono.tres",Vector2.One,Vector2.Zero),
				new FontResource("res://Fonts/Zpix.tres",Vector2.One,new Vector2(3,0))
			)},
			{"Menu",new FontSet(
				new FontResource("res://Fonts/DeterminationSans.tres",Vector2.One,Vector2.Zero),
				new FontResource("res://Fonts/Zpix.tres",Vector2.One,new Vector2(2,0))
			)}
		};
		public static Dictionary<string, VoiceProcessor> VoiceProcessors { get; } = new Dictionary<string, VoiceProcessor>(){
			{"None",new VoiceProcessor()}
		};
		public static Dictionary<string, SpecialChar> SpecialChars { get; } = new Dictionary<string, SpecialChar>{
			//Ignore invisible characters
			{" ", new SpecialChar(false, false, false)},
			{"　", new SpecialChar(false, false, false)},
			//No sound for periods and commas
			{".", new SpecialChar(true, false, true)},
			{",", new SpecialChar(true, false, true)}
		};
		public static FontSet GetFontSet(string name) => (FontSets.ContainsKey(name) ? FontSets[name] : FontSets["Default"]);
		public static ColorSet GetColorSet(string name) => (ColorSets.ContainsKey(name) ? ColorSets[name] : ColorSets["White"]);
		public static VoiceProcessor GetVoiceProcessor(string name) => (VoiceProcessors.ContainsKey(name) ? VoiceProcessors[name] : VoiceProcessors["None"]);
	}
}